#region Imports

using System;
using System.Collections.Generic;
using d3PrtDgn.Core.BaseData;

#endregion

namespace d3PrtDgn.Data.Domain.Entity
{

    [Serializable]
    public class Album : BaseEntity
    {
        #region Private Members

        // Primary Key(s) 
        private int id;

        // Foreign Keys mappate come Many-To-One 
        private Category category;
        private User owner;

        // Properties 
        private DateTime created;
        private string name;
        private string abbreviation;
        private string description;
        private Visibility visibility;

        // One-to-many relations 
        private IList<Photo> photos;

        #endregion

        #region Default ( Empty ) Class Constructor

        /// <summary>
        /// default constructor
        /// </summary>
        public Album()
        {
            id = 0;
            category = null;
            owner = null;
            created = DateTime.MinValue;
            name = null;
            abbreviation = null;
            description = null;
            photos = null;
        }

        #endregion // End of Default ( Empty ) Class Constructor

        #region Full Constructor

        /// <summary>
        /// full constructor
        /// </summary>
        public Album(int id, Category idcategory, User iduser, DateTime inserted, string name, string abbreviation, string description, Visibility visibility)
        {
            this.id = id;
            this.category = idcategory;
            this.owner = iduser;
            this.created = inserted;
            this.name = name;
            this.abbreviation = abbreviation;
            this.description = description;
            this.visibility = visibility;
            photos = null;
        }

        #endregion // End Full Constructor

        #region Required Fields Only Constructor

        /// <summary>
        /// required (not null) fields only constructor
        /// </summary>
        public Album(int id, Category idcategory, User iduser, DateTime inserted, string name, string abbreviation, Visibility visibility)
        {
            this.id = id;
            this.category = idcategory;
            this.owner = iduser;
            this.created = inserted;
            this.name = name;
            this.abbreviation = abbreviation;
            this.description = null;
            this.visibility = visibility;
            this.photos = null;
        }

        #endregion // End Required Fields Only Constructor

        #region Public Properties

        /// <summary>
        /// Unique identifier
        /// </summary>		
        public virtual int Id
        {
            get { return id; }
            set { isChanged |= (id != value); id = value; }
        }

        /// <summary>
        /// Category of album
        /// </summary>		
        public virtual Category Category
        {
            get { return category; }
            set { isChanged |= (category != value); category = value; }
        }

        /// <summary>
        /// User who owns this album
        /// </summary>		
        public virtual User Owner
        {
            get { return owner; }
            set { isChanged |= (owner != value); owner = value; }
        }

        /// <summary>
        /// Date when album was created
        /// </summary>		
        public virtual DateTime Created
        {
            get { return created; }
            set
            {
                if (created == DateTime.MinValue)
                    isChanged |= (created != value); created = value;
            }
        }

        /// <summary>
        /// Name of album
        /// </summary>		
        public virtual string Name
        {
            get { return name; }
            set
            {
                if (value != null)
                    if (value.Length > 50)
                        throw new ArgumentOutOfRangeException("Invalid value for Name", value, value.ToString());

                isChanged |= (name != value); name = value;
            }
        }

        /// <summary>
        /// URL friendly name
        /// </summary>		
        public virtual string Abbreviation
        {
            get { return abbreviation; }
            set
            {
                if (value != null)
                    if (value.Length > 50)
                        throw new ArgumentOutOfRangeException("Invalid value for Abbreviation", value, value.ToString());

                isChanged |= (abbreviation != value); abbreviation = value;
            }
        }

        /// <summary>
        /// Text description of album content
        /// </summary>		
        public virtual string Description
        {
            get { return description; }
            set
            {
                if (value != null)
                    if (value.Length > 250)
                        throw new ArgumentOutOfRangeException("Invalid value for Description", value, value.ToString());

                isChanged |= (description != value); description = value;
            }
        }

        /// <summary>
        /// Album visibility private/public
        /// </summary>		
        public virtual Visibility Visibility
        {
            get { return visibility; }
            set
            {
                isChanged |= (visibility != value); visibility = value;
            }
        }

        /// <summary>
        /// 
        /// </summary>		
        public virtual IList<Photo> Photos
        {
            get { return photos; }
            set { isChanged |= (photos != value); photos = value; }
        }

        /// <summary>
        /// Returns whether or not the object has changed it's values.
        /// </summary>
        public virtual bool IsChanged
        {
            get { return isChanged; }
        }

        /// <summary>
        /// Returns whether or not the object has changed it's values.
        /// </summary>
        public virtual bool IsDeleted
        {
            get { return isDeleted; }
        }

        #endregion

        #region Public Functions

        
        #endregion

        #region Equals And HashCode Overrides

        /// <summary>
        /// local implementation of Equals based on unique value members
        /// </summary>
        public override bool Equals(object obj)
        {
            if (this == obj) return true;
            if ((obj == null) || (obj.GetType() != this.GetType())) return false;
            Album castObj = (Album)obj;
            return (castObj != null) &&
                (this.id == castObj.Id);
        }

        /// <summary>
        /// local implementation of GetHashCode based on unique value members
        /// </summary>
        public override int GetHashCode()
        {
            int hash = 57;
            hash = 27 * hash * this.id.GetHashCode();

            return hash;

        }

        #endregion

    }
}